<template>
  <el-select
    ref="select"
    style="width:100%;"
    :multiple="showCheckbox"
    :collapse-tags="false"
    class="erp-form-tree-select__select"
    :value="selectName"
    :clearable="clearable"
    @clear="handleClearValue"
  >
    <el-option
      style="height: auto;background-color: #fff;"
      value=""
    />
    <div
      style="padding: 10px;"
      @click.stop
    >
      <el-input
        v-model="filterText"
        :clearable="true"
        placeholder="输入关键字进行过滤"
        :validate-event="false"
      >
        <template #append>
          <i class="el-icon-search" />
        </template>
      </el-input>
      <div
        v-if="!showCheckbox && topTree"
        class="top-tree-text"
      >
        <span>
          <el-button
            type="text"
            @click="setTop"
          >
            {{ topTree.label }}
          </el-button>
          <el-button
            type="text"
            @click="handleClearValue"
          >清空</el-button>
        </span>
      </div>
      <el-tree
        ref="tree"
        class="erp-form-tree-select__tree"
        v-bind="props"
        :data="computedOptions"
        :filter-node-method="filterNode"
        :default-checked-keys="showCheckbox ? valueArray : []"
        :highlight-current="true"
        @node-click="handleNodeClick"
        @check-change="handleCheckChange"
        :check-strictly="true"
      />
    </div>
  </el-select>
</template>

<script>
import Vue from 'vue';
import {Select, Option, Tree} from "element-ui";
import {request} from "../../../../request";

Vue.use(Select);
Vue.use(Option);
Vue.use(Tree);
/**
 * 下拉树选择组件
 * @author maolin
 */
export default {
  name: "ErpFormTreeSelect",
  components: {
    valueAttr () {
      return 'value';
    }
  },
  props: {
    /**
     * 标题
     * @public
     */
    title: {
      type: String,
      default: '',
    },
    /**
     * 字段名
     * @public
     */
    field: {
      type: String,
      default: ''
    },
    /**
     * 默认值
     * @public
     */
    value: {
      type: [String, Number],
      default: ''
    },
    /**
     * 树组件的配置[el-tree](https://element.eleme.cn/2.13/#/zh-CN/component/tree#props)
     * @public
     */
    props: {
      type: Object,
      default () {
        return {
        };
      }
    },
    /**
     * 默认选项
     * @public
     */
    options:{
      type: Array,
      default(){
        return [];
      }
    },
    /**
     * 额外配置
     * ```js
     * return {
          relateFields: [
            {
              field: "userId",
            }
          ],
          apiList: {
            list: {
              url: ''
            }
          }
        }
     * ```
     * @public
     */
    extra: {
      type: Object,
      default () {
        return {
          relateFields: [
            {
              field: "userId",
            }
          ],
          apiList: {
            list: {
              url: ''
            }
          }
        };
      }
    },
  },
  data () {
    return {
      currentNode: {},
      computedOptions: [],
      clearable: true,
      filterText: '',
    };
  },
  computed: {
    showCheckbox () {
      let bool = false;
      if (this.props && this.props.showCheckbox) {
        bool = true;
      }
      return bool;
    },
    disabled () {
      return !!(this.extra && this.extra.disabled);
    },
    valueKey () {
      return this.props && this.props.nodeKey ? this.props.nodeKey : 'value';
    },
    selectName: {
      get () {
        let value = this.value;
        let labelKey = this.props && this.props.props && this.props.props.label ? this.props.props.label : 'label';
        let childrenKey = this.props && this.props.props && this.props.props.children ? this.props.props.children : 'children';
        let valueKey = this.valueKey;
        let data = this.computedOptions ? this.computedOptions : [];
        if(!this.showCheckbox) {
          // 单选
          if (this.topTree) {
            if (this.topTree.value == value) {
              return this.topTree.label || '';
            }
          }
          let name = this.getTreeNameByValue(value, data, labelKey, childrenKey, valueKey);
          return name;
        } else {
          // 多选
          let selectNameArray = [];
          
          value = value ? value.split(',') : [];
          if (value && value.length > 0) {
            for (let i in value) {
              let name = this.getTreeNameByValue(value[i], data, labelKey, childrenKey, valueKey) || '';
              selectNameArray.push(name);
            }
          }
          return selectNameArray;
        }

      },
      set (value) {
        if (value === null) {
          this.currentNode = null;
        }
        if (this.extra && this.extra.relateFields && this.extra.relateFields.length > 0) {
          let relateFields = this.extra.relateFields;
          for (let i in relateFields) {
            let obj = {};
            let value = null;
            if (relateFields[i].relateField) {
              let node = this.currentNode;
              if (node) {
                value = node[relateFields[i].relateField];
              }
            }
            obj[relateFields[i].field] = value;
            this.$emit('update-id-field', obj);
          }
        }
        this.$emit('value-change', value);
      }
    },
    topTree () {
      let topTree = null;
      if (this.extra && this.extra.topTree && (this.extra.topTree.enable !== false)) {
        topTree =  this.extra.topTree;
      }
      return topTree;
    },
    valueArray () {
      return this.value ? this.value.split(',') : [];
    },
    treeLabel () {
      return this.props && this.props.props && this.props.props.label ? this.props.props.label : 'label';
    },
    listApi () {
      return this.extra && this.extra.apiList && this.extra.apiList.list ? this.extra.apiList.list : null;
    }
  },
  watch: {
    filterText(val) {
      this.$refs.tree.filter(val);
    },
    value (v){
      if (!this.showCheckbox) {
        this.$nextTick(() => {
          this.$refs.tree.setCurrentKey(this.value);
        });
      }
    },
    options: {
      handler (options) {
        if (this.extra && this.extra.apiList && this.extra.apiList.list &&  this.extra.apiList.list.url) {
          this.getComputedOptions();
        }else {
          this.computedOptions = options;
        }
      },
      immediate: true

    }
  },
  mounted() {
  },
  methods: {
    /**
     * 异步获取树选项
     * @public
     */
    getComputedOptions () {
      let api = this.listApi;
      let url = api.url || '';
      let type = 'post';
      let requestMethod = request[type];
      if (url) {
        this.loading = true;
        requestMethod(url, api.query)
          .then(res => {
            this.computedOptions = res.data.list;
          })
          .finally(() => {
            this.loading = false;
          });
      }
    },
    /**
     * 设置值为顶级树
     * @public
     */
    setTop () {
      this.selectName = this.topTree ? this.topTree.value : '';
      this.$refs.select.blur();
    },
    /**
     * 清空值
     * @public
     */
    handleClearValue () {
      this.selectName = null;
      if (this.showCheckbox) {
        let checkedNodes = this.$refs.tree.getCheckedNodes();
        if (checkedNodes && checkedNodes.length > 0) {
          for (let i = 0; i < checkedNodes.length; i ++) {
            this.$refs.tree.setChecked(checkedNodes[i][this.valueKey], false);
          }
        }
      }
    },
    /**
     * 点击树节点触发
     * @param {object} node 当前点击的树节点
     * @public
     */
    handleNodeClick (node) {
      if (this.showCheckbox) {
        return false;
      }
      this.currentNode = node;
      let valueKey = this.valueKey;
      this.selectName = node[valueKey] === undefined ? '' : node[valueKey];
      this.$refs.select.blur();
    },
    /**
     * 选择更新
     * @private
     */
    handleCheckChange () {
      let valueKey = this.valueKey;
      let checkedNodes = this.$refs.tree.getCheckedNodes();
      let valueArray = [];
      if (checkedNodes && checkedNodes.length > 0) {
        for (let i = 0; i < checkedNodes.length; i ++) {
          valueArray.push(checkedNodes[i][valueKey]);
        }
      }
      this.selectName = valueArray && valueArray.length > 0 ? valueArray.join(',') : '';
    },
    /**
     * 通过值过滤节点
     * @public
     */
    filterNode(value, data) {
      if (!value) return true;
      return data[this.treeLabel].indexOf(value) !== -1;
    },
    /**
     * 通过值获取树节点中的名称路径
     * @public
     */
    getTreeNameByValue (value, treeData, labelKey, childrenKey,  valueKey) {
      let name = null;
      return rec(value, treeData, labelKey, childrenKey, valueKey);
      function rec (value, treeData, labelKey, childrenKey, valueKey) {
        if (!treeData) return null;
        for (let i = 0; i < treeData.length; i ++) {
          if (treeData[i][valueKey] == value) {
            name = treeData[i][labelKey];
            break;
          }
          if (treeData[i][childrenKey] && treeData[i][childrenKey].length > 0) {
            rec(value, treeData[i][childrenKey],  labelKey, childrenKey,  valueKey);
          }
        }
        return name;
      }
    },
  }
};
</script>

<style lang="scss" scoped>
$primaryColor30: var(--primary-color60);
$fontSize: var(--font-size);
::v-deep{
    .erp-form-tree-select__tree{
        &.el-tree.el-tree--highlight-current{
            .el-tree-node.is-current>.el-tree-node__content{
                background-color: $primaryColor30;
            }
        }
        &.el-tree{
            .el-tree-node__label{
                font-weight: 400;
                font-size: $fontSize;
            }
        }
    }
    .el-input-group__append, .el-input-group__prepend{
        padding: 0 10px;
    }

}
.top-tree-text{
    color: #333;
    font-weight: normal;
    font-size: $fontSize;
    border-bottom: 1px dashed #d9d9d9;
}
</style>
